/**
* \file	ASTNode.cpp
* \author Caio Arce Nishibe (caionishibe@gmail.com)
* \date	August, 2014
* \brief AST Node Implementation.
*/

#include "ASTNode.h"

ASTNode::ASTNode()
{
	kind = NONE;
	lineNumber = -1;
	parent = NULL;
	children = NULL;
	sibling = NULL;

}

ASTNode::ASTNode(std::string name,  int kind, int type, int lineNumber)
{
	this->name = name;
	this->kind = static_cast<Kind>(kind);
	this->type = static_cast<Type>(type);
	this->lineNumber = lineNumber;
	
	this->parent = NULL;
	this->children = NULL;
	this->sibling = NULL;

}


ASTNode::~ASTNode()
{
	this->parent = NULL;
	this->children = NULL;
	this->sibling = NULL;
}

void ASTNode::AddSibling(ASTNode *sibling)
{
	ASTNode *temp;

	if (sibling == NULL)
		return;

	if (this->sibling == NULL)
		this->sibling = sibling;
	else
	{
		for (temp = this->sibling; temp->sibling != NULL; temp = temp->sibling);

		temp->sibling = sibling;
	}
}


void ASTNode::AddChild(ASTNode *child)
{
	ASTNode *temp;

	if (child == NULL)
		return;

	if (this->children == NULL)
	{
		child->parent = this;
		this->children = child;
	}
	else
	{
		this->children->AddSibling(child);
	}


	for (temp = child; temp != NULL; temp = temp->sibling)
		temp->parent = this;
}

void ASTNode::Accept(IVisitor *visitor)
{

	switch (this->kind)
	{
	case PROGRAM:
		visitor->VisitProgram(this);
		break;
	case NAME:
		visitor->VisitName(this);
		break;
	case IDENTIFIER:
		visitor->VisitIdentifier(this);
		break;
	case NUMBER:
		visitor->VisitNumber(this);
		break;
	case DECL:
		visitor->VisitVariable(this);
		break;
	case RULES:
		visitor->VisitRules(this);
		break;
	case RULE_SET:
		visitor->VisitRulesSet(this);
		break;
	case RULE:
		visitor->VisitRule(this);
		break;
	case CONDITION:
		visitor->VisitCondition(this);
		break;
	case LOGIC_OP:
		visitor->VisitLogicOperator(this);
		break;
	case INTERNAL_CONDITION:
		visitor->VisitInternalCondition(this);
		break;
	case COMP_OP:
		visitor->VisitComparationOperator(this);
		break;
	case ARITH_OP:
		visitor->VisitArithmeticOperator(this);
		break;
	case ARITH_EXPR:
		visitor->VisitArithmeticExpression(this);
		break;
	case ACTION:
		visitor->VisitAction(this);
		break;
	case COMMANDS:
		visitor->VisitCommand(this);
		break;
	case CMD:
		visitor->VisitCmd(this);
		break;
	case ASSIGNMENT:
		visitor->VisitAssignment(this);
		break;
	case READ_SENSOR:
		visitor->VisitReadSensor(this);
		break;
	case WRITE_ACTUATOR:
		visitor->VisitWriteActuator(this);
		break;
	case MESSAGE:
		visitor->VisitMessage(this);
		break;
	}
}